package util

import (
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"io/ioutil"
	"likeadmin/core"
	"math/rand"
	"net"
	"net/http"
	"strings"
	"time"
)

var IpUtil = ipUtil{}

// serverUtil IP工具类
type ipUtil struct{}

// GetHostIp 获取本地主机名
func (su ipUtil) GetHostIp() (ip string) {
	conn, err := net.Dial("udp", "114.114.114.114:80")
	if err != nil {
		core.Logger.Errorf("GetHostIp Dial err: err=[%+v]", err)
		return
	}
	defer conn.Close()
	localAddr := conn.LocalAddr().(*net.UDPAddr)
	return localAddr.IP.String()
}

// GetRealIp 获取真实 IP
func (su ipUtil) GetRealIp(c *gin.Context) (ip string) {
	// 优先从 X-Forwarded-For 获取
	xForwardedFor := c.Request.Header.Get("X-Forwarded-For")
	if xForwardedFor != "" {
		// X-Forwarded-For 可能包含多个IP，取第一个
		ips := strings.Split(xForwardedFor, ",")
		if len(ips) > 0 {
			return strings.TrimSpace(ips[0])
		}
	}

	// 从 X-Real-Ip 获取
	xRealIP := c.Request.Header.Get("X-Real-Ip")
	if xRealIP != "" {
		return xRealIP
	}

	// 最后使用 RemoteAddr
	remoteAddr := c.Request.RemoteAddr
	host, _, _ := net.SplitHostPort(remoteAddr)
	return host
}

// IPPlus360Response IPPlus360 API响应结构体
type IPPlus360Response struct {
	Data struct {
		Continent string `json:"continent"`
		Country   string `json:"country"`
		Prov      string `json:"prov"`
		City      string `json:"city"`
		Isp       string `json:"isp"`
	} `json:"data"`
}

// HttpAiwenCity 通过IP地址获取城市信息
func (su ipUtil) HttpAiwenCity(ip string) string {
	// 设置请求头
	header := []string{
		"Content-type:application/json;",
		"Accept:application/json",
	}

	// 如果每日访问超过5W，请增加多个key，最多两个，如超出两个，请联系相应人员
	keys := []string{
		"dMm9eepugnjijbHDrPISWfPiZjivxNE05lUyVIbPiLv9HbctzNlnv3KaAT3NAaIL",
	}

	// 随机选择一个key
	rand.Seed(time.Now().UnixNano())
	key := keys[rand.Intn(len(keys))]

	// 构造URL
	url := fmt.Sprintf("https://api.ipplus360.com/ip/geo/v1/city/?key=%s&ip=%s&coordsys=WGS84", key, ip)
	// 创建HTTP请求
	client := &http.Client{}
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return ""
	}

	// 设置请求头
	for _, h := range header {
		parts := splitHeader(h)
		if len(parts) == 2 {
			req.Header.Set(parts[0], parts[1])
		}
	}

	// 发送请求
	resp, err := client.Do(req)
	if err != nil {
		return ""
	}
	defer resp.Body.Close()

	// 读取响应
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil || len(body) == 0 {
		return ""
	}

	// 解析JSON响应
	var resData IPPlus360Response
	err = json.Unmarshal(body, &resData)
	if err != nil {
		return ""
	}

	// 获取城市信息
	return resData.Data.Continent + "-" + resData.Data.Country + "-" + resData.Data.Prov + "-" + resData.Data.City + "-" + resData.Data.Isp
}

// splitHeader 分割请求头
func splitHeader(header string) []string {
	for i := 0; i < len(header); i++ {
		if header[i] == ':' {
			return []string{header[:i], header[i+1:]}
		}
	}
	return []string{header}
}
